﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// 使用OleDb连接sql server数据库
using System.Data.OleDb;
// 使用配置
using System.Configuration;
// 获取本机IP
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;


namespace 实验7_学生成绩管理系统
{
    public partial class FormLogin : Form
    {
        string extPath = null;
        Configuration config = null;

        public FormLogin()
        {
            InitializeComponent();
        }
        private void FormLogin_Load(object sender, EventArgs e)
        {
            extPath = Application.ExecutablePath;
            config = ConfigurationManager.OpenExeConfiguration(extPath);
            if (config.AppSettings.Settings["user"] != null)
            {
                this.tb_username.Text = config.AppSettings.Settings["user"].Value;
            }
        }
        private void btn_login_Click(object sender, EventArgs e)
        {
            //
            bool loginSucceeded = false;

            // 调用自定义的工具类得到命令对象
            OleDbCommand cmd = OleDbUtil.getOleDbCommand();
            string sql = "select TOP 1 uc.USERNAME, uc.USERPASSWORD, uc.LOCKED, ll.datetime " 
                + "from useraccount uc LEFT JOIN LoginLog ll on uc.username = ll.username "
                + "and uc.USERNAME = ? order by datetime DESC";
            cmd.CommandText = sql;

            // 设置第一个占位符
            OleDbParameter param = new OleDbParameter();
            param.Value = this.tb_username.Text;
            cmd.Parameters.Add(param);
            
            // 执行命令
            OleDbDataReader reader = cmd.ExecuteReader();

            if (reader.Read())
            {
                // string datetime = reader["datetime"].ToString();
                DateTime last = Convert.ToDateTime(reader["datetime"]); // 最后一次登录时间
                DateTime now = DateTime.Now.ToLocalTime();  // 当前时间
                int userLockCount = -1;
                if (reader["userpassword"].ToString() == this.tb_password.Text && (int.Parse(reader["locked"].ToString()) < 5 || now.Subtract(last).TotalDays.CompareTo(1) != -1))
                {   // 密码正确的前提下，账号未被锁定或已过24小时，可以登录
                    // 记住账户
                    if (cbSaveUser.Checked)
                    {
                        config.AppSettings.Settings.Remove("user");
                        config.AppSettings.Settings.Add("user", this.tb_username.Text);
                    }
                    config.Save(ConfigurationSaveMode.Modified);

                    // 重置登录失败次数
                    userLockCount = 0;
                    // 登录标志
                    loginSucceeded = true;
                    // 记录登录用户的username
                    System.AppDomain.CurrentDomain.SetData("username", reader["username"]);
                    // 登录成功，设置DialogResult值，窗口会自动关闭
                    this.DialogResult = DialogResult.OK;
                    
                }
                else if (int.Parse(reader["locked"].ToString()) >= 5)
                {
                    MessageBox.Show("每日只有5次登录机会，请24小时后再尝试登录！");
                }
                else
                {
                    userLockCount = int.Parse(reader["locked"].ToString()) + 1;
                    MessageBox.Show("密码错误，登录失败！你还有" + ((5 - userLockCount) > 0 ? (5 - userLockCount) : 0) + "次机会");
                }

                if (userLockCount != -1)
                {
                    // 更新登录失败次数
                    OleDbCommand cmd2 = OleDbUtil.getOleDbCommand();
                    string sql2 = "update useraccount set locked = ? where username = ?";
                    cmd2.CommandText = sql2;
                    // 设置第一个占位符
                    param = new OleDbParameter();
                    param.Value = userLockCount.ToString();
                    cmd2.Parameters.Add(param);
                    // 设置第二个占位符
                    param = new OleDbParameter();
                    param.Value = reader["username"];
                    cmd2.Parameters.Add(param);
                    // 执行sql语句
                    cmd2.ExecuteNonQuery();

                    // 记录登录信息
                    OleDbCommand cmd3 = OleDbUtil.getOleDbCommand();
                    string sql3 = "insert into LoginLog (username, datetime, IP, succeed) values (?,?,?,?)";
                    cmd3.CommandText = sql3;

                    param = new OleDbParameter();
                    param.Value = reader["username"];
                    cmd3.Parameters.Add(param);

                    param = new OleDbParameter();
                    param.Value = DateTime.Now.ToLocalTime().ToString();
                    cmd3.Parameters.Add(param);

                    param = new OleDbParameter();
                    param.Value = GetInternalIP();
                    cmd3.Parameters.Add(param);

                    param = new OleDbParameter();
                    param.Value = (userLockCount == 0 ? 1 : 0);
                    cmd3.Parameters.Add(param);

                    cmd3.ExecuteNonQuery();
                }
            }
            else
            {
                MessageBox.Show("没有此用户，登录失败！请联系管理员注册后再登录。");
            }
            // 记录登录标志到应用程序域
            System.AppDomain.CurrentDomain.SetData("Succeed", loginSucceeded);
        }

        //获取内网IP
        private string GetInternalIP()
        {
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in nics)
            {
                foreach (var uni in adapter.GetIPProperties().UnicastAddresses)
                {
                    if (uni.Address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        return uni.Address.ToString();
                    }
                }
            }
            return null;
        }

        private void tb_TextChanged(object sender, EventArgs e)
        {
            this.btn_login.Enabled = !(string.IsNullOrEmpty(this.tb_username.Text)) && !(string.IsNullOrEmpty(this.tb_password.Text));
        }

        private void tb_usernamer_KeyUP(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter && this.tb_username.Text != null && this.tb_username.Text != "")
            {
                this.tb_password.Focus();
            }
        }
        private void tb_password_KeyUP(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter && this.tb_password.Text != null && this.tb_password.Text != "")
            {
                this.btn_login.Focus();
                this.btn_login.PerformClick();
            }
        }

    }
}
